package exo1;
import java.util.*;
import Exceptions.*;

public class Banque {
	
	private List<Compte> comptes;
	private List<String> administrateurs;
	private static int comptesCrees = 0;
	
	public Banque()
	{
		this.comptes = new ArrayList<Compte>();
		this.administrateurs = new ArrayList<String>();
	}
	
	/**
	 * Effectue la creation d'un compte.
	 */
	public boolean creerCompte()
	{	
		Scanner clavier = new Scanner(System.in);

		System.out.println("Creation d'un compte...\n");
		System.out.println("Nom du detenteur ?\n");
		
		String nom = clavier.nextLine();
		
		//Le numero de compte est égal au nombre de compte de la banque +1
		int numCompte = comptesCrees+1;
		
		System.out.println("Quel type de compte ?\n");
		System.out.println("1.Compte Epargne");
		System.out.println("2.Compte Courant");
		System.out.println("3.Compte Action");
		
		int choix = clavier.nextInt();
		
		//Solde initial du compte
		System.out.println("Solde initial?\n");
		double solde = clavier.nextDouble();

		switch(choix)
		{
			case 1 : 
				//Minimum sur operations de credit specifie a la creation et non modifiable
				System.out.println("Minimum sur operations de credit ?\n");
				double minimumCredit = clavier.nextDouble();

				try{
					CompteEpargne ce = new CompteEpargne(nom, numCompte, solde, minimumCredit);
					comptes.add(ce);
					comptesCrees++;
					return true;
				}
				catch(SoldeMinimumRequis e){
					System.out.println(e+" Valeur entree : "+e.getVersementMinimumFourni()+"\n");
				}
				break;
			case 2 : 
				//Plancher negatif a specifier
				System.out.println("Plancher negatif ?\n");
				double plancher = clavier.nextDouble();
				
				CompteCourant cc;
				cc = new CompteCourant(nom, numCompte, solde, plancher);
				
				comptes.add(cc);
				comptesCrees++;
				return true;
			case 3 : 
				//Plafond a specifier
				System.out.println("Plafond pour les operations de cr�dit?\n");
				double plafond = clavier.nextDouble();
				
				CompteAction ca;
				
				try{
					ca = new CompteAction(nom, numCompte, solde, plafond);
					comptes.add(ca);
					comptesCrees++;
					return true;
				}
				catch(SoldeMinimumRequis e){
					System.out.println(e+" Valeur entree : "+e.getVersementMinimumFourni()+"\n");
				}
				break;
				default:
					return false;
		}
	//FIN CREATION COMPTE
		return false;
	}
	/**
	 * Liste les comptes de l'utilisateur.
	 * @param nom nom du detenteur des comptes.
	 * @return liste des comptes de l'utilisateur.
	 */
	public List<Compte> listerComptes(String nom){
		
		List<Compte> listeComptes = new ArrayList<Compte>();
		/*
		String ce, cc, ca;
		ce = "Comptes Epargne :\n";
		cc = "\nComptes Courant :\n";
		ca = "\nComptes Action :\n";
		*/
		
		for(Compte temp : this.comptes){
			
			if(temp.getNom().equals(nom)){
				/*
				if(temp instanceof CompteEpargne)
					ce = ce + temp.toString();
				if(temp instanceof CompteCourant)
					cc = cc + temp.toString();
				if(temp instanceof CompteAction)
					ca = ca + temp.toString();
				*/
				
				listeComptes.add(temp);
			}
		}
		return listeComptes;
		//System.out.println("Comptes de "+nom+":\n"+ce+cc+ca);
	}
	/**
	 * Liste les comptes de la banque.
	 */
	public List<Compte> listerComptesBanque()
	{
			return this.comptes;
	}
	/**
	 * Effectue une operation de credit sur le compte.
	 * @param c compte sur lequel est effectue l'operation de credit.
	 * @param somme somme a ajouter au compte.
	 */
	public boolean creditCompte(Compte c, double montant){
		return c.crediterCompte(montant);
	}
	/**
	 * Effectue une operation de debit sur le compte.
	 * @param c Compte sur lequel est effectue l'operation de debit.
	 * @param somme Somme a retirer au compte.
	 */
	public boolean debitCompte(Compte c, double montant){
			return c.debiterCompte(montant);
	}
	/**
	 * Effectue un virement d'un compte vers un autre.
	 * @param compteEmetteur Compte emetteur de fonds.
	 * @param compteDestination Compte recepteur de fonds.
	 * @param somme Fonds à transferer sur l'autre compte.
	 */
	public boolean virementCompteToCompte(Compte compteEmetteur, Compte compteDestination, double montant)
	{
		try{
			if( compteEmetteur instanceof CompteAction){
						if(compteDestination instanceof CompteAction){
							throw new Exception("Le virement ne peut s'effectuer sur un compte action");
						}
				
						if( (compteEmetteur.getSolde() - montant) < 0 || (compteEmetteur.getSolde() - montant) < CompteAction.getVersementInitial())
						{
							throw new DebitNonAutorise("Virement non autorise, le solde devient inferieur au minimum initial("+CompteAction.getVersementInitial()+")", montant);
						}
			}
		}
		catch(Exception e){
			System.out.println(e);
			return false;
		}
		if(this.debitCompte(compteEmetteur, montant)){
			return this.creditCompte(compteDestination, montant);
		}
		return false;
	}
	/**
	 * Calcul le taux d'interet d'un compte epargne.
	 * @param ce Compte Epargne sur lequel calculer les interets.
	 */
	public boolean calculerInteret(CompteEpargne ce){
		return ce.calculerInteret();
	}
	/**
	 * Affiche le solde d'un compte.
	 * @param c Compte dont on souhaite afficher le solde.
	 */
	public void afficherSolde(Compte c){
		System.out.println("\nSolde du compte"+c.getSolde()+"\n");
	}
	/**
	 * Effectue la fermeture d'un compte.
	 * @param c Compte que l'on souhaite cloturer.
	 * @return boolean true si tout s'est bien passer
	 */
	public boolean cloturerCompte(Compte c){
		return this.comptes.remove(c);
	}
	
	/**
	 * Retourne la liste des administrateurs.
	 * @return List liste des administrateurs.
	 */
	public List<String> getAdministrateurs(){
		return this.administrateurs;
	}
	/**
	 * Retourne un compte correspondant au numero entré en parametre.
	 * @param numero Numero du compte.
	 * @return Compte correspondant au numero.
	 */
	public Compte getCompte(int numero){
		for(Compte temp : this.comptes){
			if(temp.getNumero() == numero)
				return temp;
		}
		return null;
	}

}
